package utils

import (
	"fmt"
	"runtime/debug"
	"sync"
	"time"
)

var (
	workPool *WorkerPool
	once     sync.Once
)

func GetPool(size int) *WorkerPool {
	once.Do(func() {
		workPool = NewWorkerPool(size)
	})
	return workPool
}

// Worker 定义绑定任务队列和异步回调处理的对象
type Worker struct {
	ID          int               // Worker 的唯一标识
	UserID      string            // 当前绑定的用户 ID
	TaskCh      chan interface{}  // 任务通道
	closeCh     chan struct{}     // 关闭信号
	timer       *time.Timer       // 释放定时器
	timeout     time.Duration     // 超时时间
	callback    func(interface{}) // 异步回调函数
	inProgress  bool              // 是否正在处理任务
	mu          sync.Mutex        // 用于保护状态的并发安全
	releaseFunc func(*Worker)     // 释放回调，用于返回对象池
}

// WorkerPool 定义 Worker 的对象池
type WorkerPool struct {
	mu      sync.Mutex
	workers []*Worker // 空闲 Worker 列表
	maxSize int       // 最大池大小
	counter int       // Worker 计数器
	userMap sync.Map  // 用户与 Worker 的绑定关系
}

// NewWorkerPool 初始化 Worker 池
func NewWorkerPool(maxSize int) *WorkerPool {
	return &WorkerPool{
		workers: make([]*Worker, 0, maxSize),
		maxSize: maxSize,
	}
}

// Get 从池中分配一个 Worker 对象，绑定用户
func (p *WorkerPool) Get(userID string, callback func(interface{})) *Worker {
	// 检查是否已有绑定的 Worker
	if val, ok := p.userMap.Load(userID); ok {
		w := val.(*Worker)
		w.mu.Lock()
		defer w.mu.Unlock()

		w.UserID = userID
		w.callback = callback
		w.timer.Stop() // 停止释放定时器
		return w
	}

	// 分配新的 Worker
	p.mu.Lock()
	defer p.mu.Unlock()

	var worker *Worker
	if len(p.workers) > 0 {
		// 从空闲池中获取
		worker = p.workers[len(p.workers)-1]
		p.workers = p.workers[:len(p.workers)-1]
	} else if p.counter < p.maxSize {
		// 创建新的 Worker
		worker = &Worker{
			ID:      p.counter,
			TaskCh:  make(chan interface{}, 100), // 缓冲区大小可调整
			closeCh: make(chan struct{}),
			timer:   time.NewTimer(0),
			timeout: 10 * time.Second,
		}
		p.counter++

		// 启动协程处理任务
		go worker.run()
	} else {
		// 如果池已满，返回 nil 表示分配失败
		return nil
	}

	// 初始化 Worker
	worker.mu.Lock()
	defer worker.mu.Unlock()

	worker.UserID = userID
	worker.callback = callback
	worker.inProgress = false
	worker.releaseFunc = p.release
	p.userMap.Store(userID, worker)
	return worker
}

// Submit 提交任务到绑定的 Worker
func (worker *Worker) Submit(task interface{}) {
	worker.TaskCh <- task
}

// run Worker 的任务处理主循环
func (worker *Worker) run() {
	execCallFunc := func(task interface{}) {
		defer func() {
			// 每次回调完成后启动释放定时器
			worker.startReleaseTimer()

			if err := recover(); err != nil {
				fmt.Println("WorkerPool run failed stack:", string(debug.Stack()))
			}
		}()

		worker.callback(task)
	}

	for {
		select {
		case task := <-worker.TaskCh:
			worker.mu.Lock()
			worker.inProgress = true
			worker.mu.Unlock()

			// 异步执行回调
			if worker.callback != nil {
				execCallFunc(task)
			}

			worker.mu.Lock()
			worker.inProgress = false
			worker.mu.Unlock()
		case <-worker.closeCh:
			// 收到关闭信号，退出
			return
		}
	}
}

// startReleaseTimer 启动释放定时器
func (worker *Worker) startReleaseTimer() {
	worker.mu.Lock()
	defer worker.mu.Unlock()

	if worker.timer != nil {
		worker.timer.Stop()
	}
	worker.timer = time.AfterFunc(worker.timeout, func() {
		worker.mu.Lock()
		defer worker.mu.Unlock()

		// 确认任务队列为空且没有任务正在处理时，回收对象
		if len(worker.TaskCh) == 0 && !worker.inProgress {
			worker.releaseFunc(worker)
		}
	})
}

// release 将 Worker 放回池中并清理用户绑定
func (p *WorkerPool) release(worker *Worker) {
	p.userMap.Delete(worker.UserID)

	p.mu.Lock()
	defer p.mu.Unlock()

	// 清理 Worker 状态
	worker.UserID = ""
	worker.callback = nil

	// 将 Worker 放回池中
	if len(p.workers) < p.maxSize {
		p.workers = append(p.workers, worker)
	} else {
		// 池已满，销毁 Worker
		close(worker.TaskCh)
		close(worker.closeCh)
	}
}

// Close 关闭 Worker 池
func (p *WorkerPool) Close() {
	p.mu.Lock()
	defer p.mu.Unlock()

	// 关闭所有 Worker
	for _, worker := range p.workers {
		close(worker.TaskCh)
		close(worker.closeCh)
	}
	p.workers = nil
	p.counter = 0
}
